<?php

    //require_once('../config.inc.php');
    require_once($config['app_dir'] . "/includes/db.class.php");
    require_once($config['app_dir'] . '/includes/template.class.php');
    require_once($config['app_dir'] . '/includes/session.class.php');
    require_once($config['app_dir'] . '/includes/date.class.php');
    require_once($config['app_dir'] . '/classes/DataLists.class.php');
    //----------------------------------------------------------------------------------------------------

class objCalculator {
	//allows only to create new or edit existing
	var $Years;
	var $cMonths;
	var $Months = array(1,2,3,4,5,6,7,8,9,10,11,12);
	var $test ='';
	var $dDate = array();
	var $pairsArr = array();
	var $fcastsArr = array();
	var $graphArr = array();
	var $graphArrDetailed = array();
	var $graphArrWeek = array();
    var $statsArr = array();
    var $profitArr = array();
    var $pipArr = array();//!!!20071221
	var $slippage;
	var $spreadArr;
	var $deposit;
	var $contract;
	var $trades;
	var $lossTrades = 0;
	var $winTrades = 0;
	var $tSignals = 0; //counter for provided signals
	var $tPips;
	var $tProfit;
	var $tBalance;
	var $tARR;
	var $tDdown = false;
	var $tDdownPips = false;
	var $endMonth = array();
	var $isMAP = false;

    var $timeRange = array();
    public $enable_active = false;
    public $use_def_spread = false;
    public $use_closetime = true;//!!!!!!!!!!!!20071121!!!!!!!!!!
    protected $db = false;
    public $disabled_periods=array();
    public $system=0;
    public $prevMonthProfit;
    public $currMonthName;

	//reinvestment vars
	public $lotSize;
	public $contractMult = 100000;
	public $contractAmount;
    public $reinvestStatus=false;
    public $reinvestAmountDiff = 1000;
    public $reinvestLotDiff = 0.03;
    public $reinvestLotMin = 0.1;
    public $reinvestPeriodStart = 0;

    public $reinvestModeOn = true;
    public $reinvestModeType = 'month'; //signal - re3investment on signal level; month - on month level


 		function __construct() {
			$this->db = objDataBase::GetInstance();
			$this->Years = $this->getYears();
            $this->_sqls();
      	} //constructor


        //-------------------------------------------------------------------------------------------
        // by OWL
        //-------------------------------------------------------------------------------------------

        public function Clear() {
            $this->fcastsArr = array();
            $this->graphArr = array();
            $this->graphArrDetailed = array();
            $this->graphArrWeek = array();
            $this->statsArr = array();
        } //Clear

        public function getPairs($spread=false) {
            $pairs = array();
			$pairsArr = array();
            $Pairs = new objPairsSystems();
            foreach( $Pairs->GetAssocArr()  as $pairItem )
				if( !in_array($pairItem['Pair'], $pairs) ) {
				    $this->pairsArr[] = array(
				                    'Pair' => $pairItem['Pair'],
				                    'TradeID' => $pairItem['TradeID'],
				                    'pUSD' => $pairItem['PriceUSD'],
				                    //'Spread' => $this->spreadArr[$cnter],//(!empty($this->spreadArr[$cnter]) ? $this->spreadArr[$cnter] : $rs->fields['DefaultSpread']),
				                    'Spread' => $this->spreadArr[$pairItem['TradeID']],
				                    'defSpread' => $pairItem['DefaultSpread'],
				                    'pipSize' => $pairItem['PipSize']
				                    );
					$pairs[] = $pairItem['Pair'];
				} //foreach
            return $this->pairsArr;
/*
            $pairsArr = array();
            $query = "SELECT * FROM fa_trades ORDER BY TradeID asc";

            try {
               $rs = $this->db->Execute($query);
               if ($rs){
                    $cnter=0;
                    while (!$rs->EOF) {
                        $this->pairsArr[]= array(
                                'Pair' => $rs->fields['Pair'],
                                'TradeID' => $rs->fields['TradeID'],
                                'pUSD' => $rs->fields['PriceUSD'],
                                //'Spread' => $this->spreadArr[$cnter],//(!empty($this->spreadArr[$cnter]) ? $this->spreadArr[$cnter] : $rs->fields['DefaultSpread']),
                                'Spread' => $this->spreadArr[$rs->fields['TradeID']],
                                'defSpread' => $rs->fields['DefaultSpread'],
                                'pipSize' => $rs->fields['PipSize']
                                );
                        $this->test .= ' <br>';
                        $cnter++;
                        $rs->MoveNext();
                    }//while
                }//if

         } catch(exception $e) {
            if (true == $this->db->debug ) {
              adodb_pr($e);
              $e = adodb_backtrace($e->trace);
            }
            die('DB Error: '.$e->sql);
         }
            //$this->pairsArr;
            return $this->pairsArr;
 */
        }//getPairs

        protected function CalculateForecastItem($aForecastItem) {
            //-----------------------------------------------------------------------------
            // set shorter vars for comfort calculations
            $vBegin = $aForecastItem['beginPrice'];
            $vClose = $aForecastItem['closePrice'];
            $vPip = $aForecastItem['pipSize'];
            $vSlippage = $aForecastItem['slippage'];
            $vSpread = $aForecastItem['Spread'];
            $dSpread = ( $this->use_def_spread ? $aForecastItem['defSpread'] : 0 );
            //-----------------------------------------------------------------------------
            // check if forecast for Sale / Buy
            if( 0==$aForecastItem['side'] ) {
                $aForecastItem['pips'] = round(($vClose - $vBegin)/$vPip - ($vSpread + $vSlippage) + $dSpread);

                // check if USD is first / second currency
                if( 1==$aForecastItem['pUSD'] ) {
                    $aForecastItem['profit'] = $this->contract * ( ($vClose - $vBegin) - $vPip*($vSpread + $vSlippage - $dSpread) );
                } else {
                    $aForecastItem['profit'] = $this->contract * ( (($vClose - $vBegin) - $vPip*($vSpread + $vSlippage - $dSpread))/$vClose );
                }
            } else {
                $aForecastItem['pips'] = round(($vBegin - $vClose)/$vPip - ($vSpread + $vSlippage) + $dSpread);

                if( 1==$aForecastItem['pUSD'] ) {
                    $aForecastItem['profit'] = $this->contract * ( ($vBegin - $vClose) - $vPip*($vSpread + $vSlippage - $dSpread) );
                } else {
                    $aForecastItem['profit'] = $this->contract * ( (($vBegin - $vClose) - $vPip*($vSpread + $vSlippage - $dSpread))/$vClose );
                }
            }//if check side

            $aForecastItem['profit'] *= $aForecastItem['size'];
			$aForecastItem['pips'] *= $aForecastItem['size'];
            //-----------------------------------------------------------------------------
            return $aForecastItem;
        } //calculateForecastItem

        protected function addStatsArr($aDate, $aForecastItem, $maxbalance, $monthDiff=false) {
            $currMonth = DateConvert::Date('M Y', $aDate);
            $countMonth = 0;
            if( !array_key_exists($currMonth, $this->statsArr) ) {
				$countMonth++;

                $this->statsArr[$currMonth] = array(
                                'date' => $currMonth,
                                'year' => DateConvert::Date('Y', $aDate),
                                'dateKey' => DateConvert::Date('Ym', $aDate),
                                'start' => DateConvert::Date('Y-m-01', $aDate),
                                'finish' => DateConvert::LastDayFromUnix($aDate, 'Y-m-d'),
                                'pips' => $aForecastItem['pip'],
                                'profit' => round($aForecastItem['profit']),
                                //DO NOT REMOVE !!! percent calculation based on initial deposit
                                //'profit100' => round(($aForecastItem['profit'] / $this->deposit)*100,2),
                                'profit100' => (round($aForecastItem['profit']) / ($aForecastItem['balance'] - round($aForecastItem['profit'])))*100,

                                'balance' => round($aForecastItem['balance'])/*$this->balance*/ + round($aForecastItem['profit']),
                                'tbalance' => round($aForecastItem['balance']),
                                'maxbalance' => $maxbalance
                            );



                    // reinvestment processing
            			$this->statsArr[$currMonth]['diffbalance'] = $this->prevMonthProfit;

            			if ($this->reinvestModeOn && $this->reinvestModeType == 'month')
             			$this->statsArr[$currMonth]['reinvestBalance'] = $this->processReinvestment($this->statsArr[$currMonth]['diffbalance'],true);
             			$this->statsArr[$currMonth]['lotsize'] = $this->lotSize;

						$this->prevMonthProfit = 0;
						$this->prevMonthProfit = round($aForecastItem['profit']);

            } else {
                $this->statsArr[$currMonth]['pips'] += $aForecastItem['pip'];
                $this->statsArr[$currMonth]['profit'] += round($aForecastItem['profit']);
                //DO NOT REMOVE !!! percent calculation based on initial deposit
                //$this->statsArr[$currMonth]['profit100'] += round(($aForecastItem['profit'] / $this->deposit)*100,2);
                $this->statsArr[$currMonth]['profit100'] = ($this->statsArr[$currMonth]['profit'] / ($aForecastItem['balance']- $this->statsArr[$currMonth]['profit']))*100;
                $this->statsArr[$currMonth]['balance'] += round($aForecastItem['profit']);
                $this->statsArr[$currMonth]['tbalance'] = $aForecastItem['balance'];
                $this->statsArr[$currMonth]['maxbalance'] = $maxbalance;
                $this->prevMonthProfit += round($aForecastItem['profit']);


            }
            return $this->statsArr[$currMonth];
        } //addStatsArr

        protected function addGraphArrDetailed($aDate, $aBalance) {
            // fill array for detailed graph drawing
            $this->graphArrDetailed['data']['date'][] = $aDate;
            $this->graphArrDetailed['data']['balance'][] = floatval($aBalance);
        }//addGraphArrDetailed

		//should be PUBLIC !!!
        public function addProfitPairArr($aForecastItem) {
            $TradeID = $aForecastItem['TradeID'];
            if( !array_key_exists($TradeID, $this->profitArr) ) {
                $pairItem = $this->findPairsArr($TradeID);
                $this->profitArr[$TradeID] = array(
                        'trade' => $TradeID,
                        'pair' => $pairItem['Pair'],
                        'value' => round($aForecastItem['profit'])
                    );
            } else {
                $this->profitArr[$TradeID]['value'] += round($aForecastItem['profit']);
            }
            return $this->profitArr[$TradeID];
        }//addProfitPairArr

		//should be PUBLIC !!!
        public function addPipPairArr($aForecastItem) {
            $TradeID = $aForecastItem['TradeID'];
            if( !array_key_exists($TradeID, $this->pipArr) ) {
                $pairItem = $this->findPairsArr($TradeID);
                $this->pipArr[$TradeID] = array(
                        'trade' => $TradeID,
                        'pair' => $pairItem['Pair'],
                        'value' => round($aForecastItem['pip'])
                    );
            } else {
                $this->pipArr[$TradeID]['value'] += round($aForecastItem['pip']);
            }
            return $this->pipArr[$TradeID];
        }//addPipPairArr


        public function processReinvestment($diffBalance, $riMonth=false) {
        	//$reinvestBalance;
        	if ($riMonth){
            	if (abs($diffBalance) >= $this->reinvestAmountDiff) {
                	$lotDiffMultiplyer = intval(abs($diffBalance / $this->reinvestAmountDiff));

                	if ($diffBalance>0) {
	   					 $this->lotSize += ($this->reinvestLotDiff * $lotDiffMultiplyer);
	   				} else {
	   					$negativeLot = abs($this->reinvestLotDiff * $lotDiffMultiplyer);
	   					if (($this->lotSize - $negativeLot) > $this->reinvestLotMin ) $this->lotSize -= $negativeLot;
	   					else $this->lotSize = $this->reinvestLotMin;
	   				}

            	}

               	$reinvestBalance = $diffBalance;



        	} else {
        		if(abs($this->reinvestPeriodStart) >= $this->reinvestAmountDiff) {
					$reinvestBalance = $this->reinvestPeriodStart;
	    			$lotDiffMultiplyer = intval(abs($this->reinvestPeriodStart / $this->reinvestAmountDiff));

	   				if ($this->reinvestPeriodStart>0) {
	   					 $this->lotSize += ($this->reinvestLotDiff * $lotDiffMultiplyer);
	   				} else {
	   					$negativeLot = abs($this->reinvestLotDiff * $lotDiffMultiplyer);
	   					if (($this->lotSize - $negativeLot) > $this->reinvestLotMin ) $this->lotSize -= $negativeLot;
	   					else $this->lotSize = $this->reinvestLotMin;
	   				}
	    			$this->reinvestPeriodStart = 0;

	  			} else {
	    			$reinvestBalance = $this->reinvestPeriodStart;
	    			$this->reinvestPeriodStart += $diffBalance;
	  			}
        	}



  			$this->contractAmount = $this->lotSize * $this->contractMult;
  			$this->contract = $this->contractAmount;
  			return $reinvestBalance;
        } //processReinvestment


        protected function findPairsArr($aTradeID) {
            for($i=0; $i<count($this->pairsArr); $i++)
                if( $this->pairsArr[$i]['TradeID']==$aTradeID ) return $this->pairsArr[$i];
            return false;
        }//findPairsArr

        public function clearDisabledPeriods() {
            $this->disabled_periods = array();
        } //setDisabledPeriods

        public function setDisabledPeriods($aPeriods) {
            $this->disabled_periods = $aPeriods;
        } //setDisabledPeriods

        public function addDisabledPeriods($aPeriods) {
            if( is_array($aPeriods) ) $this->disabled_periods = array_merge($this->disabled_periods, $aPeriods);
                else $this->disabled_periods[] = $aPeriods;
        } //addDisabledPeriods

        protected function getWhereClause($date_from, $date_to, $selPairs) {
            $pairs = false;
            if( !empty($selPairs) ) $pairs = implode(',', $selPairs);

            $periods = implode("','", $this->disabled_periods);
            if( $periods ) $periods = "('$where_periods')";
            //---------------------------------------------------------------------------------
            if( $this->use_closetime ) $field='COALESCE(f.CloseTime,lq.LastCloseTime)';//'CloseTime';//!!!!!!!!!!!!20071121!!!!!!!!!!
            else $field='f.BeginTime';//!!!!!!!!!!!!20071121!!!!!!!!!!

            $clauseArr = array();
            $clauseArr[] = ' s.Active=1 ';
            $clauseArr[] = " $field>='$date_from' AND $field<='$date_to'  ";
            if( !$this->enable_active ) $clauseArr[] = " f.CloseTime is not null ";
            if( $periods ) $clauseArr[] = " from_unixtime($field, '%Y%m') not in $periods ";
            if( $pairs ) $clauseArr[] = " f.TradeID IN ($pairs) ";
            if( $this->system ) $clauseArr[] = " f.SystemID = ".$this->system." ";
            $where = implode(' AND ', $clauseArr);
            if( $where ) $where = "($where)";

            return $where;
        }// WhereClause

        public function getForecastCount($date_from, $date_to, $selPairs) {
            try {
                $cnt = $this->db->handler->GetOne($this->_sql_querys['forecast_count']. " WHERE ". $this->getWhereClause($date_from, $date_to, $selPairs));
            } catch(exception $e) {
                if (true == $this->db->debug ) {
                    adodb_pr($e);
                    $e = adodb_backtrace($e->trace);
                }
                die('DB Error: '.$e->sql);
            }
            return $cnt;
        } //GetForecastCount

        public function getForecastData($date_from, $date_to, $pair_id, $selPairs) {//XXX: calc
            $this->statsArr = array();

            $fcastsItem = array();
            $balanceArr = array();
            $pipsVal = array();
            $currBalance = $this->deposit;
            $maxbalance = $this->deposit;

            $tPips = 0;
            $tProfit = 0;
            $tBalance = $this->deposit;

            ///////////////////////////////////////////////////////////////////////
              // add first point to detailed graph
              if( 0==count( $this->graphArrDetailed['data']['date'])){
                   	$this->graphArrDetailed['data']['date'][] = $date_from;
                  	$this->graphArrDetailed['data']['balance'][] = $this->deposit;
              }
            //////////////////////////////////////////////////////////////////////

            //---------------------------------------------------------------------------------
            $query = $this->_sql_querys['forecast_list']." WHERE ".$this->getWhereClause($date_from, $date_to, $selPairs)." ORDER BY CloseTime ASC ";
            //---------------------------------------------------------------------------------
            try {
                $rs = $this->db->Execute($query);
                if( $rs ) {
                    $cnter = 0;
                    while( !$rs->EOF ) {
                    ////////////////////////////////////////////////////////////////////////
                        $currMonth = date('M Y', $rs->fields['CloseTime']);

                        $this->endMonth = $currMonth;
                        $fcastsItem[$cnter]['date'] = $currMonth;
                        //-----------------------------------------------------------------------------
                        // set parametersfor each forecast (depending on fa_trades & fa_forecast & form parameters)
                        $pairsItem = $this->findPairsArr($rs->fields['TradeID']);
                        $fcastsItem[$cnter]['TradeID'] = $pairsItem['TradeID'];
                        $fcastsItem[$cnter]['pUSD'] = $pairsItem['pUSD'];
                        $fcastsItem[$cnter]['caption'] = $pairsItem['Pair'];
                        $fcastsItem[$cnter]['Spread'] = $pairsItem['Spread'];
                        $fcastsItem[$cnter]['defSpread'] = $pairsItem['defSpread'];
                        $fcastsItem[$cnter]['pipSize'] = $pairsItem['pipSize'];
                        //$fcastsItem[$cnter]['slippage'] = $this->slippage*$pairsItem['pipSize'];
                        $fcastsItem[$cnter]['slippage'] = $this->slippage;
                        //---------------------------------------------------------------------------------
                        $fcastsItem[$cnter]['beginPrice'] = $rs->fields['BeginPrice'];
                        $fcastsItem[$cnter]['closePrice'] = $rs->fields['ClosePrice'];
                        //$fcastsItem[$cnter]['lastClosePrice'] = $rs->fields['LastClosePrice'];
                        $fcastsItem[$cnter]['side'] = $rs->fields['Side'];
						$fcastsItem[$cnter]['size'] = $rs->fields['Size'];
                        //---------------------------------------------------------------------------------
                        $fcastsItem[$cnter] = $this->CalculateForecastItem($fcastsItem[$cnter]);
                        //---------------------------------------------------------------------------------
                        if( $fcastsItem[$cnter]['profit']>=0 ) $this->winTrades++;
                            else $this->lossTrades++;

                        $fcastsItem[$cnter]['pip'] = $fcastsItem[$cnter]['pips'];// count total pips
                        $currBalance +=  round($fcastsItem[$cnter]['profit']);
                        $currPips +=  $fcastsItem[$cnter]['pips'];
                        $fcastsItem[$cnter]['balance'] = $currBalance;
                        $fcastsItem[$cnter]['pips'] = $currPips;

						//-----------------------------------------------------------------------------
                        // get balances for all previous forecasts / Counting max Drawdown in $ & pips
                        if (count($balanceArr)==0) {
                        	$balanceArr[] = $this->deposit;
                        	$pipsVal[] = 0;
                        }
                        $balanceArr[] = $fcastsItem[$cnter-1]['balance'];
                        $pipsVal[] = $fcastsItem[$cnter-1]['pips'];
                        if (!$fcastsItem[$cnter-1]) {
                        	$fcastsItem[$cnter]['diffBalance'] = $fcastsItem[$cnter]['balance'] - $balanceArr[0];
                        	$fcastsItem[$cnter]['diffPips'] = $fcastsItem[$cnter]['pips'] - $pipsVal[0];
                        } else {
                        $fcastsItem[$cnter]['diffBalance'] = $fcastsItem[$cnter]['balance']-max($balanceArr);
                        	$fcastsItem[$cnter]['diffPips'] = $fcastsItem[$cnter]['pips'] - max($pipsVal);
                        }

                        if( $fcastsItem[$cnter]['diffBalance']<0 &&
                            (!$this->tDdown || ($fcastsItem[$cnter]['diffBalance']<$this->tDdown) ) ) {
                                $this->tDdown = $fcastsItem[$cnter]['diffBalance'];
                                //$this->tDdown100 = ($fcastsItem[$cnter]['diffBalance'] / $tBalance) *100;
                                //$this->tDdown100 = ($fcastsItem[$cnter]['diffBalance'] / $this->deposit) *100;
                                $this->tDdown100 = ($fcastsItem[$cnter]['diffBalance'] / $fcastsItem[$cnter]['balance']) *100;

                        }
                        if( $fcastsItem[$cnter]['diffPips']<0 &&
                            (!$this->tDdownPips || ($fcastsItem[$cnter]['diffPips']<$this->tDdownPips) ) ) {
                            $this->tDdownPips = $fcastsItem[$cnter]['diffPips'];

                        }
                        //------------------------------------------------------------------------------

                        // check if balance is MAX for curr month
                        if( $fcastsItem[$cnter]['balance'] > $fcastsItem[$cnter-1]['balance'] )
                            $maxbalance = $fcastsItem[$cnter]['balance'];

                       	//-----------------------------------------------------------------------------
                       	//debug vars - do not remove
                        $fcastsItem[$cnter]['lot'] = $this->contract;
                        $fcastsItem[$cnter]['lotSet'] = $this->lotSize;
                        $fcastsItem[$cnter]['contractAmount'] = $this->contractAmount;
                        $fcastsItem[$cnter]['contract'] = $this->contract;

                        //reinvestment handling
                        //if ($this->reinvestModeOn && $this->reinvestModeType == 'signal')
                        //$fcastsItem[$cnter]['reinvestBalance'] = $this->processReinvestment($fcastsItem[$cnter]['diffBalance']);

                        //-----------------------------------------------------------------------------
                        // fill array for detailed graph drawing
                        $this->addGraphArrDetailed($rs->fields['CloseTime'], $fcastsItem[$cnter]['balance']);
                        $this->addProfitPairArr($fcastsItem[$cnter]);
                        $this->addPipPairArr($fcastsItem[$cnter]);
                        //-----------------------------------------------------------------------------
                        //var_dump($fcastsItem[$cnter]);
                        //$this->addStatsArr($rs->fields['CloseTime'], $fcastsItem[$cnter], $maxbalance);//['BeginTime']


                        /*
                        $currMonth = date("M Y",$rs->fields['CloseTime']);
                        //$fcastsItem[$cnter]['reinvestBalance'] = $currMonth;

                        if ($this->currMonthName != $currMonth ) {

                        	$this->currMonthName = $currMonth;
                        	// reinvestment processing
                        	$diffMonthBalance = $this->prevMonthBalance;
                        	$this->prevMonthBalance = 0;
	                		$this->prevMonthBalance += round($fcastsItem[$cnter]['profit']);
	            			$fcastsItem[$cnter]['diffbalance1'] = $diffMonthBalance;

	            			if ($this->reinvestModeOn && $this->reinvestModeType == 'month')
	             			$fcastsItem[$cnter]['reinvestBalance'] = $this->statsArr[$this->currMonthName]['balance'];
	             			$fcastsItem[$cnter]['lotsize'] = $this->lotSize;
							$this->prevMonthBalance = $prevmonth;




                        } else {
                        	$this->prevMonthBalance += round($fcastsItem[$cnter]['profit']);
                        }

                         */
                        $this->addStatsArr($rs->fields['CloseTime'], $fcastsItem[$cnter], $maxbalance);//['BeginTime']

                        //-----------------------------------------------------------------------------
                        // count overall totals
                        $tPips += $fcastsItem[$cnter]['pip'];
                        $tProfit += round($fcastsItem[$cnter]['profit']);
                        $tBalance += round($fcastsItem[$cnter]['profit']);



                        $cnter++;
                        $rs->MoveNext();
                        //////////////////////////////////////////////////////////////////////////
                    }//while

                }//if rs is not empty

            } catch(exception $e) {
                if (true == $this->db->debug ) {
                    adodb_pr($e);
                    $e = adodb_backtrace($e->trace);
                }
                die('DB Error: '.$e->sql);
        }

            $this->fcastsArr = $fcastsItem;

            $this->tPips = $tPips;
            $this->tProfit = $tProfit;
            $this->tBalance = $tBalance;
            $this->test = $pipsVal;
            $this->tSignals = $cnter;
            return true;
        }//getForecastData

        //-------------------------------------------------------------------------------------------
        //end owl block
        //-------------------------------------------------------------------------------------------


		function getYears() {
        	$arrYear = array();
			$sYear = 2006;
			$cYear = date('Y');
			$this->dDate['currYear'] = $cYear;
			$this->dDate['currMonth'] = $cYear = date('n');
			$this->dDate['startYear'] = $sYear;

			for ($i=$sYear;$i<=$cYear;$i++) $arrYear[] = $i;
			return $arrYear;
      	}


       function fillGraphArrMonth($start_date) {
            $this->graphArr['data'] = array();
            $this->graphArr['data']['date'][] = $start_date;
            $this->graphArr['data']['balance'][] = floatval($this->deposit);
            foreach($this->statsArr as $month=>$record){
                $month = strtotime($month);
                $this->graphArr['data']['date'][] = mktime(23,59,59,date("m",$month)+1,00,date("Y",$month));
                $this->graphArr['data']['balance'][] = floatval($record['tbalance']);
            }
            return true;
       }

        public function fillProfitArr() {
            $result = array();
            foreach($this->profitArr as $profitKey => $profitItem) {
                $result[] =  $profitItem;
            } //foreach
            return $result;
        }//fillProfitArr

        public function fillPipArr() {
            $result = array();
            foreach($this->pipArr as $pKey => $pItem) {
                $result[] =  $pItem;
            } //foreach
            return $result;
        }//fillPipArr

       function fillGraphArrWeek($start_date){
       		$week;
       		$year;

       		$ArrWeekTime = array();
       		$ArrWeekBalance = array();
            $this->graphArrWeek['data']['date'][] = $start_date;
            $this->graphArrWeek['data']['balance'][] = floatval($this->deposit);
            $ArrWeekTime[] = $start_date;
       		$ArrWeekBalance[] = $this->deposit;
              $cntr = 0;
            foreach($this->graphArrDetailed['data']['date'] as $record){
                $aIndex = DateConvert::Date('YW',$record);
                $ArrWeekTime[$aIndex] = $record;
            	$ArrWeekBalance[$aIndex] = $this->graphArrDetailed['data']['balance'][$cntr];
                $cntr++;
            }
            $NewArrWeekTime = array();
            foreach($ArrWeekTime as $item_name => $item_value) $NewArrWeekTime[] = $item_value;

            $NewArrWeekBalance = array();
            foreach($ArrWeekBalance as $item_name => $item_value) $NewArrWeekBalance[] = $item_value;

            $this->graphArrWeek['data']['date'] = $NewArrWeekTime;
            $this->graphArrWeek['data']['balance'] = $NewArrWeekBalance;
            return true;
       }

       function formDate($y_f,$m_f,$y_t,$m_t) {
        	$lastDay;
        	for($i=28; checkdate($m_t, $i, $y_t); $i++) {
        		$lastDay = $i;
        	}
        	$this->timeRange = array(strtotime("$y_f-$m_f-01"),strtotime("$y_t-$m_t-$lastDay 23:59:59"));
			//return $timeRange;
      	}

		function separate1000($arr) {
        	for($i=0; $i<count($arr); $i++) {
        		$arr[$i]['tbalance'] = number_format($arr[$i]['tbalance']);
        	}
			return $arr;
      	}
      	function calculate($beginPrice,$closePrice,$spread,$priceUsd,$pipSize) {
        	$calcResult = array();
        	$contractSize = 100000;
        	$slippage = 3;

			$calcResult['pips'] = 'pps';
			$calcResult['profit'] = $contractSize*($closePrice - $beginPrice);
			$calcResult['balance'] = $beginPrice;


			return $calcResult;
      	}

      	function calculateTotals() {
      		$totalStats = array();

			$DDprefix = "$";
			$DDown = $this->tDdown;
			$DDownPips = $this->tDdownPips;

			// in progress.....
			//if ($DDown<0) $DDprefix = "$";
			//else $DDprefix = "$";

            $totalStats['months'] = count($this->statsArr);
            if( $this->deposit && $totalStats['months']) {
                $this->tARR = ((($this->tProfit / $this->deposit) / ($totalStats['months']) * 12))*100;
                $this->tMRR = (($this->tProfit / $this->deposit) / ($totalStats['months']) )*100;
            } else {
            	$this->tARR = 0;
            	$this->tMRR = 0;
            }
      		$totalStats['pips'] = number_format($this->tPips);
      		$totalStats['profit'] = number_format($this->tProfit);
      		$totalStats['profit100'] = round(($this->tProfit/$this->deposit)*100,2);
        	$totalStats['balance'] = number_format($this->tBalance);
            $totalStats['arr'] = round($this->tARR,2);
            $totalStats['mrr'] = round($this->tMRR,2);
            $totalStats['ddown'] = $DDprefix.number_format($DDown);
            //$totalStats['ddown100'] = round($this->tDdown100,2);
			$totalStats['ddown100'] = round((($DDown/$this->deposit)*100),2);
            $totalStats['ddownpips'] = number_format($DDownPips);
            $totalStats['wTrades'] = $this->winTrades;
            if($this->winTrades && $this->lossTrades)
                $totalStats['wTrades1'] = round( (100/($this->winTrades + $this->lossTrades))*$this->winTrades );
            else $totalStats['wTrades1'] = 0;
			$totalStats['lTrades'] = $this->lossTrades;
			$totalStats['lTrades1'] = 100 - $totalStats['wTrades1'];

			//if no signals were provided set loss trades % to 0
			if (0==$this->tSignals) $totalStats['lTrades1'] = 0;

			return $totalStats;

      	}


      	function getSystemTradesArr($systemid) {
      		if (!$this->db) return false;

      	try {
           $rs = $this->db->handler->Execute($this->_sql_querys['trades_systems'],array($systemid));
            if ($rs) {
				while (!$rs->EOF) {
					$systemTradesArr[] = $rs->fields['TradeID'];
			        $rs->MoveNext();
				}
			}
         } catch(exception $e) {
            if (true == $this->db->debug ) {
              adodb_pr($e);
              $e = adodb_backtrace($e->trace);
            }
            die('DB Error: '.$e->sql);
         }

			return $systemTradesArr;
      	}


      	function Render($Staff) {
      		$Calc = new objTemplate();
      		//$Calc->Assign('test',$this->getForecastData($this->timeRange[0],$this->timeRange[1],'2400304'));
      		$Calc->Assign('dDate',$this->dDate);
        	$Calc->Assign('pairs',$this->getPairs());
        	$Calc->Assign('spreads',array(0,1,2,3,4,5,6));
        	$Calc->Assign('UserPairs',$Staff->UserPairs());
        	$Calc->Assign('pairs_num',count($Staff->UserPairs()));
        	$Calc->Assign('sysTrades',$this->getSystemTradesArr($this->system));
	        $Calc->Assign_by_ref('Staff',$Staff);
         	$Calc->Assign_by_ref('calc',$this);

         	if ($this->isMAP) $tplFile = '_form_calc_map.tpl';
         	else $tplFile = '_form_calc.tpl';

            return $Calc->Fetch($tplFile);
      	}

        protected function _sqls() {
            //------------------------------------------------------------------
            $this->_sql_querys['_forecast_main'] =
                " FROM vfa_forecast f ".
                   " LEFT OUTER JOIN fa_trades t ON (f.TradeID = t.TradeID) ".
                   " LEFT OUTER JOIN ".
                     "(  ".
                      " SELECT ".
                           " ttq.TradeID, ".
                           " ttq.C as LastClosePrice, ".
                           " ttq.TimeStart as LastCloseTime ".
                      " FROM fa_quotes ttq ".
                          " RIGHT OUTER JOIN ( ".
                                " SELECT tq.TradeID, max(tq.TimeStart) as max_quote_time ".
                                " FROM fa_quotes tq ".
                                " GROUP BY tq.TradeID) qq ".
                                " ON (qq.max_quote_time=ttq.TimeStart and qq.TradeID=ttq.TradeID) ".
                    " ) lq ".
                    " ON (f.TradeID = lq.TradeID) ".
                    " LEFT OUTER JOIN fa_systems s ON ( s.SystemID=f.SystemID ) ";



            //------------------------------------------------------------------
            $this->_sql_querys['forecast_list'] =
            "SELECT f.BeginPrice, f.BeginTime,f.EndPrice,f.EndTime,t.TradeID,t.Pair, f.Color, f.StopPrice, f.Side, f.Size, ".//f.CloseTime,, f.ClosePrice
                " COALESCE(f.CloseTime,lq.LastCloseTime) as CloseTime,   ".
                " COALESCE(f.ClosePrice,lq.LastClosePrice) as ClosePrice   ".

                $this->_sql_querys['_forecast_main'];
            //------------------------------------------------------------------
            $this->_sql_querys['forecast_count'] =
            " SELECT count(*) ". $this->_sql_querys['_forecast_main'];

            $this->_sql_querys['trades_systems'] =  " SELECT distinct ts.TradeID ".
                                                    " FROM fa_trades_systems ts ".
                                                        " RIGHT OUTER JOIN fa_systems s ON (ts.SystemID = s.SystemID)".
                                                    " WHERE s.Active=1 AND ts.SystemID=?";

        }//_sqls

} // calculator

    function getCalcResult($aFormValues,$pairID, $system, $isMap=false) {

         $tabContent = '';
         $tradesArr = array();
         $ForecastItem = array();

         $calc = new objCalculator();
         $calc->use_def_spread = true;
         $calc->system = $system;
         $calc->formDate($aFormValues['year_from'],$aFormValues['month_from'],$aFormValues['year_to'],$aFormValues['month_to']);
         for($q=0;$q<count($aFormValues['data_trades']);$q++) $calc->spreadArr[$aFormValues['data_trades'][$q]] = $aFormValues[$aFormValues['data_trades'][$q]];
         $calc->getPairs();
         $calc->slippage = $aFormValues['data_slippage'];
         $calc->contract = $aFormValues['data_contract'];
         $calc->balance = $aFormValues['data_balance'];
         $calc->deposit = $aFormValues['data_deposit'];
    	 $calc->prevMonthBalance = $aFormValues['data_deposit'];
         $calc->trades = $aFormValues['data_trades'];
         $calc->lotSize = $aFormValues['data_lot'];
         $calc->reinvestModeOn = $aFormValues['data_reinvest'];

         // show results for all pairs or for one

         if ($pairID==1){
         	$tradesArr = $aFormValues['data_trades'];
         	$calc->getForecastData($calc->timeRange[0],$calc->timeRange[1],false,$tradesArr);
         } else {
         	$tradesArr = array($pairID);
         	$calc->getForecastData($calc->timeRange[0],$calc->timeRange[1],$pairID,$tradesArr);
         }

		 $calc->fillGraphArrMonth($calc->timeRange[0]);
		 $calc->fillGraphArrWeek($calc->timeRange[0]);

		 //if no forecasts were provided during selected period add empty graph points
		 if (2>$calc->tSignals) {

		 	// 2nd point to build equity curve
   		 	$calc->graphArrDetailed['data']['date'][] = $calc->timeRange[0]+1;
   		 	$calc->graphArrDetailed['data']['balance'][] = $calc->deposit;

			//point to bild pips / profit graph
			foreach ($tradesArr as $tradeItem){
				$ForecastItem['TradeID'] = $tradeItem;
				$ForecastItem['profit'] = 0;
				$ForecastItem['pip'] = 0;

   		 		$calc->addProfitPairArr($ForecastItem);
   		 		$calc->addPipPairArr($ForecastItem);
   		 	}
   		 }

   		global $config;
                 $Session = new objSession($config['app_id']);
   		 $Session->put('CalculatorResult',$calc->graphArr);
   		 $Session->put('CalculatorResultFcasts',$calc->graphArrDetailed);
   		 $Session->put('CalculatorResultWeek',$calc->graphArrWeek);
         if( 1==$pairID ) {
            $Session->put('CalculatorProfiTrade',$calc->fillProfitArr());
            $Session->put('CalculatorPipTrade',$calc->fillPipArr());
         }

         $cTemplate = new objTemplate();
    	 //$cTemplate->Assign('fcasts',$calc->fcastsArr);
    	 $cTemplate->Assign('fdetails',$calc->graphArrDetailed);
    	 $cTemplate->Assign('statsArr',$calc->statsArr);
    	 $cTemplate->Assign('pairs',$calc->pairsArr);
    	 $cTemplate->Assign('totals',$calc->calculateTotals());
    	 $cTemplate->Assign('selPairs',$aFormValues['data_trades']);
    	 $cTemplate->Assign('currPair',$pairID);
    	 $cTemplate->Assign('slippage',$calc->slippage);
    	 $cTemplate->Assign('spreads',$calc->spreadArr);
    	 $cTemplate->Assign('detalisation',$aFormValues['detalisation']);
    	 //$cTemplate->Assign('test',$calc->test);
    	 $cTemplate->Assign('weeks',$Session->get('CalculatorResultWeek'));
    	 $cTemplate->Assign('deposit',number_format($calc->deposit));
    	 $cTemplate->Assign('isMAP',$isMap);

         $tabContent .= $cTemplate->Fetch('_form_calc_result.tpl')/*. '<pre>'.var_export($calc->graphArrDetailed, true).'</pre>'*/;
         //----------------------------------------------------------------------
         $objResponse = new xajaxResponse();
		 $objResponse->addAssign("calcResult","innerHTML", $tabContent);
         //---------------------------------------------------------------------
         unset($calc);
         unset($aFormValues);
         unset($tabContent);
         //----------------------------------------------------------------------
         return $objResponse;
    }//getCalcResult

?>
